package com.cloud.lan.service.tx.wx.config;

import com.cloud.lan.entity.constant.WxDataConstant;
import com.cloud.lan.entity.model.dataobject.LanMpCouponDO;
import com.cloud.lan.service.ILanWxMpService;
import com.cloud.lan.service.tx.wx.WxAccessTokenService;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxRuntimeException;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author <a href="https://github.com/binarywang">Binary Wang</a>
 */
@Slf4j
@Configuration
@EnableConfigurationProperties(WxMpProperties.class)
public class WxMpConfiguration {
    @Resource
    WxAccessTokenService wxAccessTokenService;
    @Resource
    ILanWxMpService lanWxMpService;
    private static final Map<String, WxMpMessageRouter> routers = Maps.newHashMap();
    private static Map<String, WxMpService> mpServices;
    private final WxMpProperties properties;
    private final WxMpMessageHandler subscribeMsgHandler = (wxMessage, context, service, sessionManager) -> {
        String openId = wxMessage.getFromUser();
        WxMpService wxService = mpServices.get(WxDataConstant.MPAPPID);
        WxMpUser userInfo =  wxService.getUserService().userInfo(openId);
        log.info("subscribeMsgHandler openId：" + openId + ";unionId:" + userInfo.getUnionId());
        lanWxMpService.save(userInfo.getOpenId(), userInfo.getUnionId());
        String message = "您好，感谢关注兰嘉丝汀焕肌之旅公众号。\n" +
                "专研焕新科技抵御光老，邀您共绽肌肤年轻光彩。\n" +
                "\n" +
                "点击<a href=\"https://www.lancaster-beauty.com/en\" data-miniprogram-appid=\"wxe5b9fcede6680c3c\" data-miniprogram-path=\"pages/discovery-detail/index.html?id=73\">\"春日出行防晒指南\"</a>，无惧紫外线，尽情享受阳光！\n" +
                "探索<a href=\"https://www.lancaster-beauty.com/en\" data-miniprogram-appid=\"wxe5b9fcede6680c3c\" data-miniprogram-path=\"pages/discovery-detail/index.html?id=49\">下个旅行目的地</a>，根据天气环境挑选最佳防晒产品，给肌肤放个假。\n" +
                "<a href=\"https://www.lancaster-beauty.com/en\" data-miniprogram-appid=\"wxe5b9fcede6680c3c\" data-miniprogram-path=\"pages/login/index\">注册</a>成为小程序专属会员，关注品牌宠粉福利。\n" +
                "\n" +
                "点击「<a href=\"https://www.lancaster-beauty.com/en\" data-miniprogram-appid=\"wxe5b9fcede6680c3c\" data-miniprogram-path=\"pages/rewards/index\">小程序礼遇专区</a>」，解锁泰国王权免税店和新加坡樟宜机场新罗免税店专属礼遇\uD83C\uDF81!  限时领取兰嘉丝汀赠品和会员立减优惠，惊喜等你拿！";
//                "更多旅游零售与免税相关资讯、会员专属活动等即将上线，敬请期待！";
        lanWxMpService.sendKfMsg(userInfo.getOpenId(), message);

//        message = "点击领取新年限定红包封面，先到先得～兰嘉丝汀焕肌之旅预祝您2025灵蛇献瑞，贵气逼人！https://support.weixin.qq.com/cgi-bin/mmsupport-bin/showredpacket?receiveuri=NU_bH8fRI7QHAY&check_type=2#wechat_redirect";
//        lanWxMpService.sendKfMsg(userInfo.getOpenId(), message);

//        String message = "您好，感谢关注兰嘉丝汀焕肌之旅公众号。\n" +
//                "\n" +
//                "<a href=\"https://evt.cdfsunrise.com/r/page/?pageid=26DF58F52D000\">618日上免税独家通道</a>现已开启，即刻参与满600-60活动，更有3ml白金瓶体验装等你来拿！\n" +
//                "\n" +
//                "<a href=\"https://www.lancaster-beauty.com/en\" data-miniprogram-appid=\"wxe5b9fcede6680c3c\" data-miniprogram-path=\"pages/login/index\">注册</a>成为小程序会员还可实时获取旅游零售与免税相关资讯，参加会员专属的各类品牌活动、领取不定期粉丝福利！";

        lanWxMpService.sendKfMsg(userInfo.getOpenId(), "pages/location/index", "Lancaster 兰嘉丝汀焕肌之旅");

        if (!StringUtils.isBlank(wxMessage.getEventKey())
                && wxMessage.getEventKey().equals("qrscene_240711")) {
            LanMpCouponDO coupon = lanWxMpService.getMpCoupon(userInfo.getOpenId());
            if (coupon != null) {
                lanWxMpService.sendKfMsg(userInfo.getOpenId(), "恭喜你获得code为：" + coupon.getCode());
            }
        }

//        String otherMessage = "你最理想的夏日度假圣地是哪？点击下方聊天框与我们分享你的回答，即有机会获得品牌超值好礼！活动截止日期为9月30日，请勿错过机会！\n" +
//                "\n" +
//                "每位参加者须关注Lancaster公众号并留言分享你最理想的夏日度假圣地，答得最有创意的5位参加者，即可获得兰嘉丝汀柔润洁面乳 (400ml)1件及兰嘉丝汀御颜眼霜 (15ml)1件，（總值 ¥1,119）。\n" +
//                "\n" +
//                "如有任何争议，Lancaster 保留最终决定权，包括随时暂停、更改或终止活动及其条款及细则，而毋须另行通知。";
//        lanWxMpService.sendKfMsg(userInfo.getOpenId(), otherMessage);
        lanWxMpService.startMsg(userInfo.getOpenId());
        return null;
    };

    private final WxMpMessageHandler textMsgHandler = (wxMessage, context, service, sessionManager) -> {
        String openId = wxMessage.getFromUser();
        WxMpService wxService = mpServices.get(WxDataConstant.MPAPPID);
        WxMpUser userInfo =  wxService.getUserService().userInfo(openId);
        lanWxMpService.replyMsg(userInfo.getOpenId(), wxMessage.getContent());
        return null;
    };

    @Autowired
    public WxMpConfiguration(WxMpProperties properties) {
        this.properties = properties;
    }

    public String reFreshWXTk(String appid) {
        WxMpService wxService = mpServices.get(appid);
        if (wxService == null) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
        }
        try {
            String wxTk = wxService.getAccessToken(true);
            wxAccessTokenService.add(appid, wxTk);
            log.info("新增 accessToken 到 redis ：{}", wxTk);
            return wxTk;
        } catch (Exception e) {
            log.error("获取 getAccessToken 失败", e);
        }
        return null;
    }

    public static WxMpService getMpService(String appid) {
        WxMpService wxService = mpServices.get(appid);
        if (wxService == null) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid));
        }

        return wxService;
    }

    public static WxMpMessageRouter getRouter(String appid) {
        return routers.get(appid);
    }

    @PostConstruct
    public void init() {
        List<WxMpProperties.Config> configs = this.properties.getConfigs();
        if (configs == null) {
            throw new WxRuntimeException("大哥，拜托先看下项目首页的说明（readme文件），添加下相关配置，注意别配错了！");
        }

        mpServices = configs.stream()
                .map(a -> {
                    WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
                    // 使用上面的配置时，需要同时引入jedis-lock的依赖，否则会报类无法找到的异常
                    config.setAppId(a.getAppid());
                    config.setSecret(a.getSecret());
                    config.setToken(a.getToken());
                    config.setAesKey(a.getAesKey());

                    WxMpService service = new WxMpServiceImpl();
                    service.setWxMpConfigStorage(config);
                    routers.put(a.getAppid(), this.newRouter(service));
                    return service;
                }).collect(Collectors.toMap(s -> s.getWxMpConfigStorage().getAppId(), a -> a));
    }

    private WxMpMessageRouter newRouter(WxMpService service) {
        final WxMpMessageRouter router = new WxMpMessageRouter(service);
        router.rule().msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.SUBSCRIBE).handler(subscribeMsgHandler).end();
//        router.rule().msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.SUBSCRIBE).handler(subscribeMsgHandler).end().rule()
//                .msgType(WxConsts.XmlMsgType.TEXT).handler(textMsgHandler).end();
//        router.rule().event(WxConsts.XmlMsgType.EVENT).eventKey(WxConsts.EventType.SUBSCRIBE).handler(subscribeMsgHandler).end();
//        router.rule().msgType(WxConsts.EventType.SUBSCRIBE).handler(subscribeMsgHandler).end();
        return router;
    }

}
